package com.bootdo.payee.service.impl;

import static com.bootdo.common.utils.ShiroUtils.getUserId;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.bootdo.common.config.Constant;
import com.bootdo.common.redis.lock.CommonRedisLock;
import com.bootdo.common.utils.DateUtils;
import com.bootdo.common.utils.MD5Utils;
import com.bootdo.common.utils.StringUtils;
import com.bootdo.mq.RabbitUtil;
import com.bootdo.mq.SendSortUtil;
import com.bootdo.payee.dao.PayeeAgentDao;
import com.bootdo.payee.dao.PayeeDao;
import com.bootdo.payee.dao.PaymentCodeDao;
import com.bootdo.payee.domain.PayeeAgentDO;
import com.bootdo.payee.domain.PayeeDO;
import com.bootdo.payee.domain.PaymentCodeDO;
import com.bootdo.payee.service.PayeeAgentService;
import com.bootdo.quota.dao.QuotaDao;
import com.bootdo.quota.dao.QuotaHistoryDao;
import com.bootdo.quota.domain.QuotaDO;
import com.bootdo.quota.domain.QuotaHistoryDO;
import com.bootdo.rate.dao.RateDao;
import com.bootdo.rate.domain.RateDO;
import com.bootdo.system.dao.UserDao;
import com.bootdo.system.dao.UserRoleDao;
import com.bootdo.system.domain.UserDO;
import com.bootdo.system.domain.UserRoleDO;

/**
 * 收款户代理管理
 */
@Service
public class PayeeAgentServiceImpl implements PayeeAgentService {

    @Autowired
    private UserDao userMapper;
    @Autowired
    private PayeeAgentDao payeeAgentMapper;
    @Autowired
    private UserRoleDao userRoleMapper;
    @Autowired
    private RateDao rateMapper;
    @Autowired
    private QuotaDao quotaMapper;
    @Autowired
    private PayeeDao payeeMapper;
    @Autowired
    private RabbitUtil rabbitUtil;
    @Autowired
    private QuotaHistoryDao quotaHistoryMapper;
    @Autowired
    private PaymentCodeDao paymentCodeMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private SendSortUtil sendSortUtil;

    /**
     * 获取收款户代理列表
     * @param map
     * @return
     */
    @Override
    public List<PayeeAgentDO> list(Map<String, Object> map){
        //获取用户权限
        int checkUserIsManager = userRoleMapper.checkUserIsManager(getUserId());
        if (checkUserIsManager != 1){
            map.put("userIdCreate", getUserId());
        }
        return payeeAgentMapper.list(map);
    }

    /**
     * 获取收款户代理列表总条数
     * @param map
     * @return
     */
    @Override
    public int count(Map<String, Object> map){
        //获取用户权限
        int checkUserIsManager = userRoleMapper.checkUserIsManager(getUserId());
        if (checkUserIsManager != 1){
            map.put("userIdCreate", getUserId());
        }
        return payeeAgentMapper.count(map);
    }

    /**
     * 添加收款户代理
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    public int save(PayeeAgentDO payeeAgentDO){
        payeeAgentDO.setUserName(payeeAgentDO.getUserName().trim());
        payeeAgentDO.setName(payeeAgentDO.getName().trim());
        //添加用户表
        UserDO userDO = new UserDO();
        userDO.setUsername(payeeAgentDO.getUserName());
        userDO.setPassword(payeeAgentDO.getPassword());
        userDO.setStatus(1);
        userDO.setMobile(payeeAgentDO.getMobile());
        userMapper.save(userDO);

        Long userId = userDO.getUserId();
        userRoleMapper.removeByUserId(userId);
        UserRoleDO ur = new UserRoleDO();
        ur.setUserId(userId);
        ur.setRoleId(61L);
        userRoleMapper.save(ur);

        payeeAgentDO.setUserId(userId);
        payeeAgentDO.setUserIdCreate(getUserId());
        payeeAgentDO.setGmtCreate(new Date());
        int count = payeeAgentMapper.save(payeeAgentDO);

        //设置额度
        QuotaDO quota = new QuotaDO();
        quota.setUserId(userId);
        quota.setActualQuota(payeeAgentDO.getQuota());
        quota.setChangeReason("初始额度");
        quota.setStatus(1);
        quota.setActualQuota(payeeAgentDO.getQuota() == null ? 0.00 : payeeAgentDO.getQuota());
        quota.setQuota(payeeAgentDO.getQuota() == null ? 0.00 : payeeAgentDO.getQuota());
        quota.setChangeType(0);
        quota.setGmtDate(new Date());
        quotaMapper.save(quota);
        //插入历史表
        QuotaHistoryDO quotaHistory = new QuotaHistoryDO();
        quotaHistory.setUserId(userId);
        quotaHistory.setQuota(payeeAgentDO.getQuota() == null ? 0.00 : payeeAgentDO.getQuota());
        quotaHistory.setActualQuota(payeeAgentDO.getQuota() == null ? 0.00 : payeeAgentDO.getQuota());
        quotaHistory.setChangeReason("初始额度");
        quotaHistory.setStatus(1);
        quotaHistory.setChangeType(0);
        quotaHistory.setGmtDate(new Date());
        quotaHistory.setVersion(1);
        quotaHistoryMapper.save(quotaHistory);
        return count;
    }


    /**
     * 获取指定收款户代理信息
     * @param id
     * @return
     */
    @Override
    public PayeeAgentDO get(Long id) {
        PayeeAgentDO payeeAgent = payeeAgentMapper.get(id);
        QuotaDO quota = quotaMapper.get(id);
        payeeAgent.setQuota(quota.getActualQuota());
        RateDO rate = rateMapper.getRate(payeeAgent.getUserId(), 0);
        if (rate != null){
            payeeAgent.setWeixinFixedRate(rate.getWeixinFixedRate());
            payeeAgent.setAlipayFixedRate(rate.getAlipayFixedRate());
            payeeAgent.setAlipayTransferRate(rate.getAlipayTransferRate());
            payeeAgent.setAlipayAccountTransRate(rate.getAlipayAccountTransRate());
        }
        return payeeAgent;
    }


    /**
     * 更新收款户代理
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    public int update(PayeeAgentDO payeeAgentDO){
        if (StringUtils.isNotBlank(payeeAgentDO.getUserName())){
            payeeAgentDO.setUserName(payeeAgentDO.getUserName().trim());
        }
        if (StringUtils.isNotBlank(payeeAgentDO.getName())){
            payeeAgentDO.setName(payeeAgentDO.getName().trim());
        }
        String password = payeeAgentDO.getPassword();
        PayeeAgentDO payeeAgent = payeeAgentMapper.get(payeeAgentDO.getUserId());
        if (StringUtils.isBlank(password) || password.equals(payeeAgent.getPassword())){
            payeeAgentDO.setPassword(null);
        } else {
            payeeAgentDO.setPassword(MD5Utils.encrypt(payeeAgent.getUserName(), password));
            UserDO user = new UserDO();
            user.setUserId(payeeAgentDO.getUserId());
            user.setPassword(payeeAgentDO.getPassword());
            userMapper.update(user);
        }
        int count = payeeAgentMapper.update(payeeAgentDO);

        //修改额度
        QuotaDO quota = quotaMapper.get(payeeAgentDO.getUserId());
        if (payeeAgentDO.getQuota() != null && payeeAgentDO.getQuota().doubleValue() != quota.getActualQuota().doubleValue()){
            JSONObject object = new JSONObject();
            object.put("date", DateUtils.format(new Date(),DateUtils.DATE_TIME_PATTERN));
            object.put("userId", payeeAgentDO.getUserId());
            object.put("money",payeeAgentDO.getQuota());
            object.put("orderId", "");
            if (payeeAgentDO.getQuota().doubleValue() > quota.getActualQuota().doubleValue()){
                object.put("reason", "平台调整增加");
                object.put("type", 1);
            } else {
                object.put("reason", "平台调整减少");
                object.put("type", 2);
            }
            rabbitUtil.sendToQueue(Constant.UPDATE_QUOTA, object.toJSONString());
        }
        return count;
    }


    /**
     * 收款户代理状态修改
     * @param userId
     * @param status
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    public int editStatus(Long userId, Integer status){
        PayeeAgentDO payeeAgentDO = new PayeeAgentDO();
        payeeAgentDO.setUserId(userId);
        payeeAgentDO.setGmtModified(new Date());
        payeeAgentDO.setStatus(status);
        int count = payeeAgentMapper.update(payeeAgentDO);

        //修改用户状态
        UserDO user = new UserDO();
        user.setUserId(payeeAgentDO.getUserId());
        user.setStatus(payeeAgentDO.getStatus());
        userMapper.update(user);

        Set<Integer> set = new CopyOnWriteArraySet<>();
        if (payeeAgentDO.getStatus() == 0){
            //收款户代理禁用后需要将所有的下属收款户禁用
            PayeeDO payee = new PayeeDO();
            payee.setUserIdCreate(payeeAgentDO.getUserId());
            payee.setStatus(payeeAgentDO.getStatus());
            payee.setLineUpStatus(0);
            payeeMapper.editStatusByCreate(payee);

            Map<String,Object> map = new HashMap<>();
            map.put("userIdCreate", payeeAgentDO.getUserId());
            List<PayeeDO> lists = payeeMapper.list(map);
            List<Long> list = new ArrayList<>();
            for (PayeeDO payees : lists){
                payees.setLineUpStatus(0);
                payeeMapper.update(payees);
                //退出当前代理下面所有收款户的排队
                CommonRedisLock commonRedisLock = new CommonRedisLock(stringRedisTemplate);
                PaymentCodeDO paymentCode = paymentCodeMapper.getCodeByOk(payees.getUserId());
                if (paymentCode != null) {
                    boolean f = commonRedisLock.searchListByValue(Constant.PASSAGEWAY + paymentCode.getPassagewayId(), String.valueOf(paymentCode.getUserIdCreate()));
                    if (f){
                        commonRedisLock.lRemove(Constant.PASSAGEWAY + paymentCode.getPassagewayId(), 0, String.valueOf(paymentCode.getUserIdCreate()));
                        JSONObject object = new JSONObject();
                        String queueName = Constant.QUEUE_START+paymentCode.getUserIdCreate();
                        object.put("code",3);
                        object.put("date", DateUtils.format(new Date(),DateUtils.DATE_TIME_PATTERN));
                        object.put("userId",paymentCode.getUserIdCreate());
                        object.put("msg","代理已被禁用，请联系管理员");
                        object.put("payType", paymentCode.getPassagewayId());
                        rabbitUtil.sendToQueue(queueName,object.toJSONString());
                    }
                    set.add(paymentCode.getPassagewayId());
                }
                list.add(payees.getUserId());
            }
            if (list.size() > 0) {
                userMapper.batchStatus(list);
            }
            sendSortUtil.sendMsg(set);
        }
        return count;
    }

    /**
     * 重置收代令牌
     * @param id
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    public int resetToken(Long id){
        return userMapper.removeSecretById(id);
    }

}
